// store/table-state.svelte.ts
import { type ColumnConfig, type SortDirection, type SummaryType } from '../context/table-context';
import { debounce } from 'lodash-es';
import {
	createComparator,
	getHeaderTree,
	getLeafColumns,
	getLeafKeys,
	calculateAggregate,
	generateSummaryCells,
	isValueEqual
} from '../utils/common';
import * as XLSX from 'xlsx'; // 🔥 引入 xlsx

// 定义构造函数参数接口
interface TableStateOptions<T> {
	data: T[];
	// 接收外部传入的合计方法
	summaryMethod?: (params: { columns: ColumnConfig[]; data: T[] }) => Record<string, any>;
}

export class TableState<T extends Record<string, any> = Record<string, any>> {
	// 常量
	MAX_FILTER_OPTIONS = 1000;
	// 原始 props
	rawData = $state<T[]>([]);
	rootColumns = $state<ColumnConfig[]>([]);

	// 🔥 新增：存储全局合计方法
	globalSummaryMethod?: (params: { columns: ColumnConfig[]; data: T[] }) => Record<string, any>;

	// 状态
	columnWidths = $state<Record<string, number>>({});
	sortState = $state<{ key: string; direction: SortDirection }[]>([]);
	optionFilterState = $state<Record<string, (string | number)[]>>({});
	keywordFilterState = $state<Record<string, (string | number)[]>>({});
	customFilterState = $state<Record<string, any>>({});

	// 可显示列状态的set
	visibleColumns = $state<Set<string>>(new Set());
	visibleVersion = $state(0); // 用于强制刷新可见列

	// 多选相关
	selectedKeys = $state<Set<string | number>>(new Set());
	isExcludeMode = $state(false); // true=全选排除模式
	selectionVersion = $state(0); // 用于强制刷新多选框

	// 滚动相关
	bodyScrollbarWidth = $state(0);
	bodyScrollbarHeight = $state(0);

	// 衍生状态
	columns = $derived(getLeafColumns(this.rootColumns));
	headerData = $derived(getHeaderTree(this.rootColumns)); // 表头树结构，包含对象cols, maxDepth

	// 处理后的数据 (排序+筛选)
	processedData = $state<T[]>([]);
	isLoading = $state(false);

	// 合计数据
	showSummary = $state(true);
	summaryData = $state<Record<string, any>>({});
	summaryCells = $derived.by(() => {
		if (Object.keys(this.summaryData).length === 0) return [];
		return generateSummaryCells(this.columns, this.summaryData, this.columnWidths);
	});

	// 🔥 修改构造函数，接收对象参数
	constructor({ data, summaryMethod }: TableStateOptions<T>) {
		this.rawData = data;
		this.globalSummaryMethod = summaryMethod; // 保存外部传入的方法
		// console.log('constructor', $state.snapshot(this.rawData));
	}

	setData(data: T[]) {
		this.rawData = data;
		// console.log('setData', $state.snapshot(data));
	}

	addColumn(config: ColumnConfig) {
		if (!this.rootColumns.some((col) => col.key === config.key)) {
			// 默认为 true
			if (config.visible === undefined) config.visible = true;
			this.rootColumns.push(config);
			// console.log('addColumn', config);
			if (config.visible) {
				this.visibleColumns.add(config.key as string);
			}
		}
	}

	/** 实现上下文方法：移除列 */
	removeColumn = (key: ColumnConfig['key']) => {
		const index = this.rootColumns.findIndex((col) => col.key === key);
		if (index !== -1) {
			this.rootColumns.splice(index, 1);
			this.visibleColumns.delete(key as string);
			delete this.columnWidths[key as string];
			// 清理排序和筛选状态
			this.sortState = this.sortState.filter((item) => item.key !== key);
			if (this.optionFilterState[key as string] !== undefined) {
				delete this.optionFilterState[key as string];
			}
			if (this.keywordFilterState[key as string] !== undefined) {
				delete this.keywordFilterState[key as string];
			}
			if (this.customFilterState[key as string] !== undefined) {
				delete this.customFilterState[key as string];
			}
		}
	};

	// /**
	//  * 批量更新列的可见性
	//  * @param visibilityMap Key 是列的 key，Value 是可见性 boolean
	//  */
	// updateColumnsVisibility(visibilityMap: Record<string, boolean>) {
	// 	// 1. 只需要一次深度遍历即可处理所有变更
	// 	this._recursiveUpdateVisibility(this.rootColumns, visibilityMap);
	// }

	// /**
	//  * 内部递归辅助方法
	//  */
	// private _recursiveUpdateVisibility(cols: ColumnConfig[], map: Record<string, boolean>) {
	// 	for (const col of cols) {
	// 		const key = col.key as string;

	// 		// 如果当前列在 map 中，更新它
	// 		if (key in map) {
	// 			col.visible = map[key];
	// 			// 2. 更新 visibleColumns set
	// 			if (col.visible) {
	// 				this.visibleColumns.add(key);
	// 			} else {
	// 				this.visibleColumns.delete(key);
	// 			}
	// 			// console.log(this.visibleColumns,cols)
	// 		}

	// 		// 继续递归子节点
	// 		if (col.children && col.children.length > 0) {
	// 			this._recursiveUpdateVisibility(col.children, map);
	// 		}
	// 	}
	// }

	// //  单个调用
	// toggleColumnVisibility(key: string, visible: boolean) {
	// 	this.updateColumnsVisibility({ [key]: visible });
	// }

	// 🔥 新增：更新根列的顺序 (简化版：仅支持顶层列拖拽排序)
	updateRootColumnOrder(newOrderKeys: string[]) {
		const newCols: ColumnConfig[] = [];
		const colMap = new Map(this.rootColumns.map((c) => [c.key as string, c]));

		newOrderKeys.forEach((key) => {
			const col = colMap.get(key);
			if (col) {
				newCols.push(col);
				colMap.delete(key);
			}
		});

		// 如果有遗漏的（不应该发生），追加到后面
		colMap.forEach((col) => newCols.push(col));

		this.rootColumns = newCols;
	}

	// 🔥 新增：导出 Excel
	exportToExcel(fileName: string = 'table-export') {
		if (this.processedData.length === 0) {
			console.warn('无数据可导出');
			return;
		}

		// 1. 获取当前显示的列（扁平化）
		const visibleColumns = this.columns; // this.columns 已经是 getLeafColumns 的结果，且 common.ts 中已过滤 visible

		// 2. 转换数据
		// 我们需要把数据转换成 Key-Value 形式，Key 最好是 Title
		const exportData = this.processedData.map((row) => {
			const rowData: Record<string, any> = {};
			visibleColumns.forEach((col) => {
				// 优先使用 title，如果有重复 title，可能需要处理，这里简单处理
				const headerName = col.title || (col.key as string);

				// 这里可以加入 formatter 的逻辑，如果列配置有 formatter
				// 简单起见直接取值
				const val = (row as any)[col.key];
				rowData[headerName] = val;
			});
			return rowData;
		});

		// 3. 创建 Workbook
		const worksheet = XLSX.utils.json_to_sheet(exportData);
		const workbook = XLSX.utils.book_new();
		XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');

		// 4. 导出
		XLSX.writeFile(workbook, `${fileName}.xlsx`);
	}

	// --- 排序逻辑 ---
	handleSort(key: string, multi: boolean) {
		// 查找当前列是否已在排序列表中
		const existingIndex = this.sortState.findIndex((item) => item.key === key);

		if (multi) {
			// --- 多列排序模式 (追加/修改) ---
			if (existingIndex > -1) {
				// 如果已存在，切换方向: ascend -> descend -> remove
				const currentDir = this.sortState[existingIndex].direction;
				if (currentDir === 'ascend') {
					this.sortState[existingIndex].direction = 'descend';
				} else {
					// 再次点击降序，移除该列排序
					this.sortState.splice(existingIndex, 1);
				}
			} else {
				// 如果不存在，追加到末尾
				this.sortState.push({ key, direction: 'ascend' });
			}
		} else {
			// --- 单列排序模式 (替换) ---
			if (existingIndex > -1 && this.sortState.length === 1) {
				// 如果当前只有这一列在排序，且点击的是它，则循环方向
				const currentDir = this.sortState[0].direction;
				if (currentDir === 'ascend') {
					this.sortState[0].direction = 'descend';
				} else {
					this.sortState = []; // 清空
				}
			} else {
				// 否则，清空其他所有排序，只保留当前列
				this.sortState = [{ key, direction: 'ascend' }];
			}
		}

		this.triggerProcessData(this.rawData);
	}

	setFilter(key: string, value: any, type: 'option' | 'string' | 'customize' | 'delete') {
		const keyStr = String(key);
		if (type === 'delete') {
			delete this.optionFilterState[keyStr];
			delete this.keywordFilterState[keyStr];
			delete this.customFilterState[keyStr];
			this.triggerProcessData(this.rawData);
			return;
		}
		if (type === 'option') {
			delete this.keywordFilterState[keyStr];
			delete this.customFilterState[keyStr];
			const oldValue = this.optionFilterState[keyStr];
			// 核心：一致性判断 - 新旧值一致则直接返回，不执行后续操作
			if (isValueEqual(oldValue, value)) {
				return;
			}

			// 如果值为undefined或null，则删除该筛选条件
			if (value === undefined || value === null || (Array.isArray(value) && value.length === 0)) {
				delete this.optionFilterState[keyStr];
			} else {
				this.optionFilterState[keyStr] = value;
			}
			this.triggerProcessData(this.rawData);
		} else if (type === 'string') {
			delete this.optionFilterState[keyStr];
			delete this.customFilterState[keyStr];
			const oldValue = this.keywordFilterState[keyStr];
			// 核心：一致性判断 - 新旧值一致则直接返回，不执行后续操作
			if (isValueEqual(oldValue, value)) {
				return;
			}

			// 如果值为undefined或null，则删除该筛选条件
			if (value === undefined || value === null || (Array.isArray(value) && value.length === 0)) {
				delete this.keywordFilterState[keyStr];
			} else {
				this.keywordFilterState[keyStr] = value;
			}
			this.triggerProcessData(this.rawData);
		} else if (type === 'customize') {
			delete this.optionFilterState[keyStr];
			delete this.keywordFilterState[keyStr];
			const oldValue = this.customFilterState[keyStr];
			// 核心：一致性判断 - 新旧值一致则直接返回，不执行后续操作
			if (isValueEqual(oldValue, value)) {
				return;
			}
			// 如果值为undefined或null，则删除该筛选条件
			if (value === undefined || value === null || value === '') {
				delete this.customFilterState[keyStr];
			} else {
				this.customFilterState[keyStr] = value;
			}
			this.triggerProcessData(this.rawData);
		}
	}

	// --- 多选逻辑 ---
	toggleRowSelection(rowId: string | number, checked: boolean) {
		if (this.isExcludeMode) {
			checked ? this.selectedKeys.delete(rowId) : this.selectedKeys.add(rowId);
		} else {
			checked ? this.selectedKeys.add(rowId) : this.selectedKeys.delete(rowId);
		}
		this.selectionVersion++;
	}

	toggleAllSelection(checked: boolean) {
		this.isExcludeMode = checked;
		this.selectedKeys.clear();
		this.selectionVersion++;
	}

	triggerProcessData = debounce(async (dataToProcess: T[]) => {
		this.isLoading = true;
		// 快速路径：如果数据为空，直接返回
		if (dataToProcess.length === 0) {
			this.processedData = [];
			return;
		}

		// 模拟异步，避免阻塞 UI
		await new Promise((r) => setTimeout(r, 0));

		let result: T[] = dataToProcess;

		// 1、先处理数据筛选
		// 预先提取出活跃的筛选条件，避免在循环中重复查找
		const activeOptionFilters = this.columns.filter(
			(col) =>
				col.filterable &&
				this.optionFilterState[col.key] &&
				this.optionFilterState[col.key].length > 0
		);
		const activeKeywordFilters = this.columns.filter(
			(col) =>
				col.filterable &&
				this.keywordFilterState[col.key] &&
				this.keywordFilterState[col.key].length > 0
		);
		// 🔥 新增：找出有自定义筛选值 且 提供了 onFilter 函数的列
		const activeCustomFilters = this.columns.filter(
			(col) =>
				col.filterable &&
				this.customFilterState[col.key] !== undefined &&
				typeof col.onFilter === 'function'
		);

		const hasFilters =
			activeOptionFilters.length > 0 ||
			activeKeywordFilters.length > 0 ||
			activeCustomFilters.length > 0;

		// 仅在有筛选时进行单次遍历
		if (hasFilters) {
			result = result.filter((item) => {
				// 检查选项筛选
				for (const col of activeOptionFilters) {
					if (!this.optionFilterState[col.key].includes(item[col.key])) return false;
				}
				// 检查关键字筛选
				for (const col of activeKeywordFilters) {
					const val = String(item[col.key]).toLowerCase();
					const keywords = this.keywordFilterState[col.key];
					// 假设 keyword 是 OR 关系，只要匹配一个即可；如果是 AND 改为 every
					if (!keywords.some((k) => val.includes(String(k).trim().toLowerCase()))) {
						return false;
					}
				}
				// 🔥 新增：检查自定义筛选
				for (const col of activeCustomFilters) {
					const filterVal = this.customFilterState[col.key];
					// 调用父组件提供的 onFilter(筛选值, 行数据)
					// 如果返回 false，则过滤掉该行
					if (!col.onFilter!(filterVal, item)) {
						return false;
					}
				}
				return true;
			});
		}

		//2、在处理排序
		if (this.sortState.length > 0) {
			// 如果 result 仍然等于 dataToProcess，说明没有经过筛选（filter会生成新数组）。
			// 此时必须进行浅拷贝，否则 sort 会修改原始 data，导致取消排序后无法恢复原样。
			if (result === dataToProcess) {
				result = [...result];
			}
			// 为每个参与排序的列检测数据类型并创建比较器
			const comparators = this.sortState.map((state) => {
				const keyStr = state.key;
				const sortDir = state.direction;
				let keyType: 'string' | 'number' | 'mixed' = 'mixed';
				const targetCol = this.columns.find((col) => col.key === keyStr);

				if (targetCol?.keyType) {
					keyType = targetCol.keyType;
				} else if (result.length > 0) {
					// 采样检测类型
					const sampleSize = Math.min(20, result.length);
					let hasString = false;
					let hasNumber = false;
					for (let i = 0; i < sampleSize; i++) {
						const value = result[i][keyStr];
						if (value == null) continue;
						if (typeof value === 'string') hasString = true;
						else if (typeof value === 'number') hasNumber = true;
						if (hasString && hasNumber) break;
					}
					keyType = hasString && hasNumber ? 'mixed' : hasString ? 'string' : 'number';
				}

				// 返回一个包含比较器和key的对象
				return {
					key: keyStr,
					compare: createComparator(sortDir, keyType)
				};
			});

			// 执行排序
			// 注意：由于多列排序比较复杂，这里不再使用 map-sort 优化（Schwartzian transform）
			// 除非在此处构建复杂的复合键，否则直接 sort 的性能通常是可以接受的
			result.sort((a, b) => {
				for (const { key, compare } of comparators) {
					const valA = a[key];
					const valB = b[key];
					// 如果值不相等，直接返回比较结果
					// createComparator 内部通常处理了相等返回 0 的情况，
					// 但我们需要显式判断是否继续比较下一列
					const res = compare(valA, valB);
					if (res !== 0) {
						return res;
					}
					// 如果 res === 0，循环继续，比较下一个排序条件
				}
				return 0; // 所有排序列都相等
			});
		}

		this.processedData = result;
		//情况多选
		this.isExcludeMode = false;
		this.selectedKeys.clear();
		this.selectionVersion++;

		// 3. 计算合计
		if (this.showSummary) {
			this.calculateSummary(result);
		}

		this.isLoading = false;
	}, 16);

	// 辅助：计算分组表头的总宽度
	getGroupWidth = (col: ColumnConfig) => {
		const keys = getLeafKeys(col);
		// 使用 getColWidthVal 获取实时宽度
		const total = keys.reduce((sum, key) => {
			const wStr = this.columnWidths[key];
			const w = wStr ? wStr : 0;
			return sum + w;
		}, 0);
		return total;
	};

	getColWidthVal = (key: string) => {
		const w = this.columnWidths[key];
		return w ? w : 0;
	};

	calculateSummary(currentData: T[]) {
		if (!this.showSummary) return;

		// 1. 全局自定义方法优先
		if (this.globalSummaryMethod) {
			this.summaryData = this.globalSummaryMethod({ columns: this.columns, data: currentData });
			// 生成单元格结构（计算宽度合并）
			this.summaryCells = generateSummaryCells(this.columns, this.summaryData, this.columnWidths);
			return;
		}

		const sums: Record<string, any> = {};

		this.columns.forEach((col) => {
			const key = col.key as string;

			// A. 静态文本 (summaryText)
			if (col.summaryText !== undefined) {
				sums[key] = col.summaryText;
				return;
			}

			// B. 如果该列被前面的列合并覆盖了（例如 summaryColSpan=0 这种手动配置，虽然我们主要靠 generateSummaryCells 自动处理）
			// 这里主要关注是否开启了 summary
			if (!col.summary) {
				sums[key] = '';
				return;
			}

			// C. 列级自定义方法 (summaryMethod)
			if (col.summaryMethod) {
				sums[key] = col.summaryMethod(currentData);
				return;
			}

			// D. 自动聚合计算
			// 判断聚合类型：如果是 true，默认为 sum
			const type: SummaryType = col.summary === true ? 'sum' : (col.summary as SummaryType);

			const values = currentData.map((item) => item[key]);
			const result = calculateAggregate(values, type);

			if (result !== null) {
				// E. 格式化 (summaryFormatter)
				if (col.summaryFormatter) {
					sums[key] = col.summaryFormatter(result);
				} else {
					sums[key] = result;
				}
			} else {
				sums[key] = '';
			}
		});

		this.summaryData = sums;
		// 生成渲染用的单元格数据（处理宽度和合并）
		this.summaryCells = generateSummaryCells(this.columns, this.summaryData, this.columnWidths);
	}
}
